package com.ruoyi.device.service.impl;

import java.util.*;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.ruoyi.common.core.utils.DateUtils;
import com.ruoyi.common.core.utils.http.HttpUtils;
import com.ruoyi.device.domain.DeviceInfo;
import com.ruoyi.device.mapper.DeviceInfoMapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.ruoyi.device.mapper.DeviceCollectConfigMapper;
import com.ruoyi.device.domain.DeviceCollectConfig;
import com.ruoyi.device.service.IDeviceCollectConfigService;

/**
 * 设备采集配置Service业务层处理
 * 
 * @author ruoyi
 * @date 2025-10-20
 */
@Service
public class DeviceCollectConfigServiceImpl implements IDeviceCollectConfigService 
{
    private static final Logger log = LoggerFactory.getLogger(DeviceCollectConfigServiceImpl.class);

    @Autowired
    private DeviceCollectConfigMapper deviceCollectConfigMapper;

    @Autowired
    private DeviceInfoMapper deviceInfoMapper;

    /**
     * 查询设备采集配置
     * 
     * @param configId 设备采集配置主键
     * @return 设备采集配置
     */
    @Override
    public DeviceCollectConfig selectDeviceCollectConfigByConfigId(Long configId)
    {
        return deviceCollectConfigMapper.selectDeviceCollectConfigByConfigId(configId);
    }

    /**
     * 查询设备采集配置列表
     * 
     * @param deviceCollectConfig 设备采集配置
     * @return 设备采集配置
     */
    @Override
    public List<DeviceCollectConfig> selectDeviceCollectConfigList(DeviceCollectConfig deviceCollectConfig)
    {
        return deviceCollectConfigMapper.selectDeviceCollectConfigList(deviceCollectConfig);
    }

    /**
     * 新增设备采集配置
     * 
     * @param deviceCollectConfig 设备采集配置
     * @return 结果
     */
    @Override
    public int insertDeviceCollectConfig(DeviceCollectConfig deviceCollectConfig)
    {
        deviceCollectConfig.setCreateTime(DateUtils.getNowDate());
        return deviceCollectConfigMapper.insertDeviceCollectConfig(deviceCollectConfig);
    }

    /**
     * 修改设备采集配置
     * 
     * @param deviceCollectConfig 设备采集配置
     * @return 结果
     */
    @Override
    public int updateDeviceCollectConfig(DeviceCollectConfig deviceCollectConfig)
    {
        deviceCollectConfig.setUpdateTime(DateUtils.getNowDate());
        return deviceCollectConfigMapper.updateDeviceCollectConfig(deviceCollectConfig);
    }

    /**
     * 批量删除设备采集配置
     * 
     * @param configIds 需要删除的设备采集配置主键
     * @return 结果
     */
    @Override
    public int deleteDeviceCollectConfigByConfigIds(Long[] configIds)
    {
        return deviceCollectConfigMapper.deleteDeviceCollectConfigByConfigIds(configIds);
    }

    /**
     * 删除设备采集配置信息
     * 
     * @param configId 设备采集配置主键
     * @return 结果
     */
    @Override
    public int deleteDeviceCollectConfigByConfigId(Long configId)
    {
        return deviceCollectConfigMapper.deleteDeviceCollectConfigByConfigId(configId);
    }

    /**
     * 启动采集任务
     * 
     * @param configId 配置ID
     * @return 结果
     */
    @Override
    public int startCollectTask(Long configId)
    {
        DeviceCollectConfig config = new DeviceCollectConfig();
        config.setConfigId(configId);
        config.setStatus("1");
        config.setUpdateTime(DateUtils.getNowDate());
        return deviceCollectConfigMapper.updateDeviceCollectConfig(config);
    }

    /**
     * 停止采集任务
     * 
     * @param configId 配置ID
     * @return 结果
     */
    @Override
    public int stopCollectTask(Long configId)
    {
        DeviceCollectConfig config = new DeviceCollectConfig();
        config.setConfigId(configId);
        config.setStatus("0");
        config.setUpdateTime(DateUtils.getNowDate());
        return deviceCollectConfigMapper.updateDeviceCollectConfig(config);
    }

    /**
     * 执行设备状态采集同步
     * 
     * @param configId 配置ID
     */
    @Override
    public void executeCollect(Long configId)
    {
        DeviceCollectConfig config = deviceCollectConfigMapper.selectDeviceCollectConfigByConfigId(configId);
        if (config == null)
        {
            log.error("采集配置不存在: {}", configId);
            return;
        }

        if (!"1".equals(config.getStatus()))
        {
            log.info("采集配置已停用: {}", configId);
            return;
        }

        log.info("开始执行设备状态采集, 配置ID: {}", configId);

        try
        {
            // 收集所有在线设备ID
            Set<String> onlineDeviceIds = new HashSet<>();
            
            int currentPage = 1;
            int totalPages = 1;
            
            // 分页采集所有数据
            while (currentPage <= totalPages)
            {
                String url = config.getApiUrl() + "?page=" + currentPage + "&page_size=" + config.getPageSize();
                
                Map<String, String> headers = new HashMap<>();
                headers.put("Authorization", config.getAuthorization());
                headers.put("Content-Type", "application/json");
                
                String response = HttpUtils.sendGet(url, headers);
                
                if (response == null || response.isEmpty())
                {
                    throw new Exception("接口返回为空");
                }
                
                JSONObject jsonResponse = JSON.parseObject(response);
                
                // 检查令牌是否有效
                if (!jsonResponse.getBooleanValue("success"))
                {
                    Integer code = jsonResponse.getInteger("code");
                    String message = jsonResponse.getString("message");
                    
                    if (code != null && code == 40001)
                    {
                        log.error("Authorization令牌无效或已过期: {}", message);
                        updateCollectStatus(configId, "FAILED", "Authorization令牌无效: " + message, false);
                        return;
                    }
                    
                    throw new Exception("接口返回失败: " + message);
                }
                
                JSONObject data = jsonResponse.getJSONObject("data");
                if (data == null)
                {
                    throw new Exception("接口返回数据为空");
                }
                
                // 计算总页数
                int total = data.getIntValue("total");
                int pageSize = data.getIntValue("page_size");
                totalPages = (int) Math.ceil((double) total / pageSize);
                
                log.info("采集第 {}/{} 页, 共 {} 条数据", currentPage, totalPages, total);
                
                JSONArray items = data.getJSONArray("items");
                if (items != null && !items.isEmpty())
                {
                    for (int i = 0; i < items.size(); i++)
                    {
                        JSONObject item = items.getJSONObject(i);
                        String deviceId = item.getString("s"); // 接口返回的 's' 字段对应设备ID
                        
                        if (deviceId != null && !deviceId.isEmpty())
                        {
                            onlineDeviceIds.add(deviceId);
                        }
                    }
                }
                
                currentPage++;
            }
            
            log.info("采集完成, 在线设备数量: {}", onlineDeviceIds.size());
            
            // 更新设备状态
            updateDeviceStatus(onlineDeviceIds);
            
            // 更新采集状态
            updateCollectStatus(configId, "SUCCESS", "成功采集 " + onlineDeviceIds.size() + " 个在线设备", true);
            
        }
        catch (Exception e)
        {
            log.error("设备状态采集失败", e);
            updateCollectStatus(configId, "FAILED", "采集失败: " + e.getMessage(), false);
        }
    }

    /**
     * 更新设备在线状态
     * 
     * @param onlineDeviceIds 在线设备ID集合
     */
    private void updateDeviceStatus(Set<String> onlineDeviceIds)
    {
        Date now = DateUtils.getNowDate();
        
        // 查询所有设备
        DeviceInfo queryParam = new DeviceInfo();
        List<DeviceInfo> allDevices = deviceInfoMapper.selectDeviceInfoList(queryParam);
        
        int onlineCount = 0;
        int offlineCount = 0;
        
        for (DeviceInfo device : allDevices)
        {
            String deviceId = device.getDeviceId();
            Integer currentStatus = device.getStatus();
            
            if (onlineDeviceIds.contains(deviceId))
            {
                // 设备在线
                if (currentStatus == null || currentStatus != 1)
                {
                    device.setStatus(1); // 在线
                    device.setLastHeartbeat(now);
                    deviceInfoMapper.updateDeviceInfo(device);
                    onlineCount++;
                }
            }
            else
            {
                // 设备离线
                if (currentStatus == null || currentStatus != 0)
                {
                    device.setStatus(0); // 离线
                    deviceInfoMapper.updateDeviceInfo(device);
                    offlineCount++;
                }
            }
        }
        
        log.info("设备状态更新完成 - 上线: {}, 离线: {}", onlineCount, offlineCount);
    }

    /**
     * 更新采集状态
     * 
     * @param configId 配置ID
     * @param status 状态
     * @param message 消息
     * @param success 是否成功
     */
    private void updateCollectStatus(Long configId, String status, String message, boolean success)
    {
        DeviceCollectConfig config = new DeviceCollectConfig();
        config.setConfigId(configId);
        config.setLastCollectTime(DateUtils.getNowDate());
        config.setLastCollectStatus(status);
        config.setLastCollectMessage(message);
        
        // 更新统计
        DeviceCollectConfig currentConfig = deviceCollectConfigMapper.selectDeviceCollectConfigByConfigId(configId);
        if (currentConfig != null)
        {
            long totalCollected = currentConfig.getTotalCollected() == null ? 0 : currentConfig.getTotalCollected();
            long successCollected = currentConfig.getSuccessCollected() == null ? 0 : currentConfig.getSuccessCollected();
            long failedCollected = currentConfig.getFailedCollected() == null ? 0 : currentConfig.getFailedCollected();
            
            config.setTotalCollected(totalCollected + 1);
            config.setSuccessCollected(success ? successCollected + 1 : successCollected);
            config.setFailedCollected(success ? failedCollected : failedCollected + 1);
        }
        
        deviceCollectConfigMapper.updateDeviceCollectConfig(config);
    }
}

